﻿using Fall.Core.Reflaction;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Fall.Core.IOC;

namespace Fall.Core.Extensions
{
    public static class IOCExtensions
    {
        /// <summary>
        /// 自动注册服务
        /// </summary>
        /// <param name="services">注册服务的集合（向其中注册）</param>
        /// <param name="ImplementationType">要注册的类型</param>
        public static void AutoRegisterService(this IServiceCollection services, Type ImplementationType)
        {
            var attr = ImplementationType.GetCustomAttribute(typeof(InjectAttribute)) as InjectAttribute;
            var types = attr.GetTargetTypes();
            var lifetime = attr.Lifetime;
            foreach (var t in types)
            {
                var serviceDescriptor = new ServiceDescriptor(t, ImplementationType, lifetime);
                services.Add(serviceDescriptor);
            }
        }
        #region 程序集注入
        /// <summary>
        /// 程序集注入
        /// </summary>
        /// <param name="services">IServiceCollection</param>
        /// <param name="AassemblyName">程序集名字</param>
        public static void AutoRegisterServicesFromAssembly(this IServiceCollection services, string AassemblyName)
        {
            var types = AssemblyHelper.GetTypesByAssemblyName(AassemblyName);
            AutoRegisterServicesFromTypes(services, types);
        }
        /// <summary>
        /// 程序集注入
        /// </summary>
        /// <param name="services">IServiceCollection</param>
        /// <param name="AassemblyName">程序集名字</param>
        /// <param name="wherelambda">过滤类型的表达式</param>
        public static void AutoRegisterServicesFromAssembly(this IServiceCollection services,
            string AassemblyName, Func<Type, bool> wherelambda)
        {
            var types = AssemblyHelper.GetTypesByAssemblyName(AassemblyName);
            var typeList = types.Where(wherelambda);
            AutoRegisterServicesFromTypes(services, typeList);
        }
        /// <summary>
        /// 程序集注入
        /// </summary>
        /// <param name="services">IServiceCollection</param>
        /// <param name="moduleType">程序集ModuleType</param>
        public static void AutoRegisterServicesFromAssembly(this IServiceCollection services, Type moduleType)
        {
            Type[] types = AssemblyHelper.GetTypesByModuleType(moduleType);
            AutoRegisterServicesFromTypes(services, types);
        }

        private static void AutoRegisterServicesFromTypes(IServiceCollection services,IEnumerable<Type> types) 
        {
            var _types = types.Where(t => t.IsClass && !t.IsAbstract);
            foreach (var t in _types)
            {
                IEnumerable<Attribute> attrs = t.GetCustomAttributes();
                foreach (var attr in attrs)
                {
                    if (attr is InjectAttribute)
                    {
                        services.AutoRegisterService(t);
                        break;
                    }
                }
            }
        }
        #endregion
    }
}
